/**
 * @description 登录、获取用户信息、退出登录、清除token逻辑，不建议修改
 */
import Api from '@/api'
import { getToken, removeToken, setToken } from '@/utils/token'
import { isString } from '@/utils/validate'
import { tokenName } from '@/config'

const state = () => ({
  token: getToken(),
  userInfo: {},
})
const getters = {
  token: (state) => state.token,
  userInfo: (state) => state.userInfo,
}
const mutations = {
  /**
   * @description 设置token
   * @param {*} state
   * @param {*} token
   */
  setToken(state, token) {
    state.token = token
    setToken(token)
  },
  /**
   * @description 设置用户信息
   * @param {*} state
   * @param {*} userInfo
   */
  setUserInfo(state, userInfo) {
    state.userInfo = userInfo
  },
}
const actions = {
  /**
   * @description 登录
   * @param {*} { commit }
   * @param {*} userInfo
   */
  async login({ commit }, userInfo) {
    const { data } = await Api.user.login(userInfo)
    const token = data[tokenName]
    if (token) {
      commit('setToken', token)
    } else {
      const err = '登录异常'
      throw err
    }
  },
  /**
   * @description 获取用户信息接口 这个接口非常非常重要，如果没有明确底层前逻辑禁止修改此方法，错误的修改可能造成整个框架无法正常使用
   * @param {*} { commit, dispatch, state }
   * @returns
   */
  async getUserInfo({ commit }) {
    const { data } = await Api.user.getUserInfo()
    const { username } = data
    /**
     * 检验返回数据是否正常，无对应参数，将使用默认用户名,头像,Roles和Ability
     * username {String}
     * avatar {String}
     * roles {List}
     * ability {List}
     */
    if (username && !isString(username)) {
      const err = 'getUserInfo核心接口异常，请检查返回JSON格式是否正确'
      throw err
    } else {
      // 如不使用username用户名,可删除以下代码
      if (username) commit('setUserInfo', data)
    }
  },
  /**
   * @description 退出登录
   * @param {*} { dispatch }
   */
  async logout({ dispatch }) {
    await Api.user.logout()
    await dispatch('resetAll')
  },
  /**
   * @description 重置token、roles、ability、router、tabsBar等
   * @param {*} { commit, dispatch }
   */
  async resetAll({ dispatch }) {
    await dispatch('setToken', '')
    await dispatch('setUserInfo', [])
    removeToken()
  },
  /**
   * @description 设置token
   * @param {*} { commit }
   * @param {*} token
   */
  setToken({ commit }, token) {
    commit('setToken', token)
  },
  setUserInfo({ commit }, userInfo) {
    commit('userInfo', userInfo)
  },
}
export default { state, getters, mutations, actions }
